package com.wn.login

import android.content.Context
import android.content.Intent
import android.text.SpannableStringBuilder
import android.text.method.HideReturnsTransformationMethod
import android.text.method.LinkMovementMethod
import android.text.method.PasswordTransformationMethod
import android.widget.EditText
import android.widget.TextView
import androidx.activity.viewModels
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.blankj.utilcode.util.ToastUtils
import com.wn.common.provider.UserServiceProvider
import com.wn.framework.base.BaseActivity
import com.wn.framework.ext.onClick
import com.wn.framework.ext.textChangeFlow
import com.wn.login.utils.stringSetSpan
import com.wn.login.view.RegisterActivity
import com.wn.login.viewmodel.LoginViewModel
import com.wn.mod_login.R
import com.wn.mod_login.databinding.ActivityLoginBinding
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch

/**
 * @Author: wn
 * @Date: 2025/6/26 15:41
 * @Description: 登录页面
 */
@AndroidEntryPoint
class LoginActivity : BaseActivity<ActivityLoginBinding>() {

  override fun getLayoutRes() = R.layout.activity_login

  private val viewModel by viewModels<LoginViewModel>()

  // 密码是否可见
  private var isShowPassword = true


  override fun initView() {
    initAgreement()
    initListener()
    mBinding.etPhone.apply {
      /**
       * 设置 手机号 输入框的初始值
       * 移动光标到文本末尾
       * xml 设置密码不可见
       */
      setText(UserServiceProvider.getUserPhone())
      setSelection(length())
    }
  }

  /**
   * 初始化协议 是否勾选
   */
  private fun initAgreement() {
    mBinding.cbAgreement.apply {
      // 我已阅读并同意 《隐私政策》 及 《用户服务协议》
      val agreement = getString(com.wn.framework.R.string.login_agreement)
      val privacySpan = getString(com.wn.framework.R.string.login_privacy_agreement)
      val serviceSpan = getString(com.wn.framework.R.string.login_user_agreement)
      runCatching {
        // 创建一个 SpannableStringBuilder 对象
        val spaBuilder = SpannableStringBuilder(agreement)
        // 启用文本中的超链接点击功能
        movementMethod = LinkMovementMethod.getInstance()
        //《隐私政策》
        stringSetSpan(spaBuilder, privacySpan, this@LoginActivity)
        // 我已阅读并同意 《隐私政策》 及 《用户服务协议》
        stringSetSpan(spaBuilder, serviceSpan, this@LoginActivity)
        // 为 CheckBox 重新赋值 文本
        setText(spaBuilder, TextView.BufferType.SPANNABLE)
      }
        .onFailure {
          text = agreement
        }
    }
  }

  /**
   * 初始化监听器
   */
  private fun initListener() {
    mBinding.apply {
      // 是否显示 密码
      ivPasswordToggle.onClick {
        togglePassword()
      }
      // 忘记密码
      tvForgetPassword.onClick {
        ToastUtils.showLong("忘记密码功能暂未实现，请联系管理员")
      }
      // 注册
      tvRegister.onClick {
        RegisterActivity.toRegister(this@LoginActivity)
      }
      // 登陆
      tvLogin.onClick {
        toLogin()
      }
      // 勾选框 事件
      cbAgreement.setOnCheckedChangeListener { _, isChecked ->
        updateLoginState(isChecked)
      }
      // 输入框变化 -- 更新 登录按钮 状态
      etPhone.apply {
        setEditTextChange(this)
      }
      etPassword.apply {
        setEditTextChange(this)
      }
    }
  }

  /**
   * 更新登录按钮状态 -- 勾选框选中时，且  登陆按钮为可点击状态
   */
  private fun updateLoginState(isChecked: Boolean) {
    mBinding.apply {
      val phoneEnable = etPhone.run {
        val phone = text.toString()
        phone.isNotEmpty() && phone.length == 11
      }

      val passwordEnable = etPassword.run {
        val password = text.toString()
        password.isNotEmpty()
      }
      // 更新 登陆按钮 状态
      tvLogin.isSelected = phoneEnable && passwordEnable && isChecked
      tvLogin.isEnabled = phoneEnable && passwordEnable && isChecked
    }
  }

  /**
   * 切换密码是否可见
   */
  private fun togglePassword() {
    isShowPassword = !isShowPassword
    mBinding.apply {
      if (isShowPassword) {
        // 显示密码
        ivPasswordToggle.setImageResource(com.wn.framework.R.mipmap.ic_psw_invisible)
        etPassword.transformationMethod = HideReturnsTransformationMethod.getInstance()
      } else {
        // 隐藏密码
        ivPasswordToggle.setImageResource(com.wn.framework.R.mipmap.ic_psw_visible)
        etPassword.transformationMethod = PasswordTransformationMethod.getInstance()
      }
      // 移动光标到文本末尾
      etPassword.setSelection(etPassword.length())
    }
  }

  /**
   * 设置 EditText 文本变化监听
   * @param editText EditText
   */
  @OptIn(FlowPreview::class)
  private fun setEditTextChange(editText: EditText) {
    editText.textChangeFlow()
//      .filter { it.isNotEmpty() } // 过滤空内容 后面需要对此进行 判空，此处不过滤
      .debounce(300) // 300ms防抖
      .flowOn(Dispatchers.IO) // 在 IO 线程执行
      .onEach {
        // 更新登录按钮状态
        updateLoginState(mBinding.cbAgreement.isChecked)
      }
      .launchIn(lifecycleScope) // 在生命周期范围内收集流 终止操作符  一般搭配 onEach 一起使用
  }

  /**
   * 登陆
   */
  private fun toLogin() {
    mBinding.apply {
      val userName = etPhone.text?.trim().let { it.toString() ?: "" }
      val password = etPassword.text?.trim().let { it.toString() ?: "" }
      if (userName.isEmpty() || userName.length < 11) {
        ToastUtils.showLong(getString(com.wn.framework.R.string.error_phone_number))
        return
      }
      if (password.isEmpty()) {
        ToastUtils.showLong(com.wn.framework.R.string.error_input_password)
        return
      }
      // viewModel  login
      doLogin(userName, password)
    }
  }

  private lateinit var loginJob: Job
  private fun doLogin(userName: String, password: String) {
    if (::loginJob.isInitialized) loginJob.cancel()
    loginJob = lifecycleScope.launch {
      lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
        // 登陆
        launch {
          viewModel.login(userName, password).collect {
            it ?: return@collect
            /**
             * 成功提示
             * 保存 账号 + 用户信息
             * 关闭当前页
             */
            ToastUtils.showLong(com.wn.framework.R.string.success_login)
            UserServiceProvider.saveUserInfo(it)
            UserServiceProvider.saveUserPhone(it.username)
            finish()
          }
        }

        // 加载 loading
        launch {
          viewModel.loading.collect {
            if (it) showLoading() else dismissLoading()
          }
        }
      }
    }
  }

  companion object {
    /**
     * 跳转到登录页面
     * @param context Context
     */
    fun toLogin(context: Context) {
      val intent = Intent(context, LoginActivity::class.java)
      context.startActivity(intent)
    }
  }

  /**
   * Home键或者锁屏 后 如果不 cancel 返回时数据会重复请求  -- stop
   * viewPager 滑动 -- pause
   */
  override fun onStop() {
    if (::loginJob.isInitialized) loginJob.cancel()
    super.onStop()
  }
}